package com.easy.common.util;
import java.math.BigDecimal;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

import com.easy.common.constant.Const;

public class Amount {


	private static DecimalFormat numFormat = new DecimalFormat("#0.00");
	private static DecimalFormat numFormatG = new DecimalFormat("#,##0.00");
	public static final int decimalScale = 2;
	private static final String[] CN_UPPER_NUMBER = { "零", "壹", "贰", "叁", "肆","伍", "陆", "柒", "捌", "玖" };
	//汉语中货币单位大写，这样的设计类似于占位符
	private static final String[] CN_UPPER_MONETRAY_UNIT = { "分", "角", "元","拾", "佰", "仟", "万", "拾", "佰", "仟", "亿", "拾", "佰", "仟", "兆", "拾","佰", "仟" };
	//特殊字符：整
	private static final String CN_FULL = "整";//特殊字符：负
	private static final String CN_NEGATIVE = "负";//金额的精度，默认值为2
	private static final int MONEY_PRECISION = 2;//特殊字符：零元整
	private static final String CN_ZEOR_FULL = "零元" + CN_FULL;//把输入的金额转换为汉语中人民币的大写

	@SuppressWarnings("rawtypes")
	private static final Class Amount = null;

	private static final String enSmallNumber[] = {
		"", "ONE", "TWO", "THREE", "FOUR", "FIVE", "SIX", "SEVEN", "EIGHT", "NINE", 
		"TEN", "ELEVEN", "TWELVE", "THIRTEEN", "FOURTEEN", "FIFTEEN", "SIXTEEN", "SEVENTEEN", "EIGHTEEN", "NINETEEN"
	};
	private static final String enLargeNumber[] = {
		"TWENTY", "THIRTY", "FORTY", "FIFTY", "SIXTY", "SEVENTY", "EIGHTY", "NINETY"
	};
	private static final String enUnit[] = {
		"", "THOUSAND", "MILLION", "BILLION", "TRILLION"
	};	
	public Amount()
	{
	}

	/**
	 * 将Decimal定点数转换为字符串
	 * @param num　定点数 Decimal
	 * @param pattern 0为千分位格式分隔如1,322.01　　1常规格式如 1322.01 
	 * @return 返回指定格式字符串
	 */
	public static String getFormatedStr(BigDecimal num, int pattern)
	{
		if(num==null)return "0.00";
		if (pattern == 1)
			return numFormat.format(num);
		else
			return numFormatG.format(num);
	}

	/**
	 * 将double浮点数转换为字符串
	 * @param num　浮点数 double
	 * @param pattern 0为千分位格式分隔如1,322.01　　1常规格式如 1322.01 
	 * @return 返回指定格式字符串
	 */
	public static String getFormatedStr(double num, int pattern)
	{
		if (pattern == 1)
			return numFormat.format(num);
		else
			return numFormatG.format(num);
	}

	/**
	 * 将字符串数据转换为指定数据格式的字符串
	 * @param num　浮点数 double
	 * @param pattern 0为千分位格式分隔如1,322.01　　1常规格式如 1322.01 
	 * @return 返回指定格式字符串
	 */
	public static String getFormatedStr(String numStr, int pattern)
	{
		String rtStr = "0.00";
		try
		{
			double dValue = parseDouble(numStr);
			if (pattern == 1)
				rtStr = numFormat.format(dValue);
			else
				rtStr = numFormatG.format(dValue);
		}
		catch (Exception exception) { }
		return rtStr;
	}


	private static String positiveIntegerToChinsesStr(String numStr)
	{
		String chineseDigiStr[] = {
			"零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"
		};
		String chineseDiviStr[] = {
			"", "拾", "佰", "仟", "万", "拾", "佰", "仟", "亿", "拾", 
			"佰", "仟", "万", "拾", "佰", "仟", "亿", "拾", "佰", "仟", 
			"万", "拾", "佰", "仟"
		};
		String rmbStr = "";
		boolean lastzero = false;
		boolean hasvalue = false;
		int len = numStr.length();
		if (len > 15)
			return I18n.ln(Amount, "2");
		for (int i = len - 1; i >= 0; i--)
			if (numStr.charAt(len - i - 1) != ' ')
			{
				int n = numStr.charAt(len - i - 1) - 48;
				if (n < 0 || n > 9)
					return I18n.ln(Amount, "3");
				if (n != 0)
				{
					if (lastzero)
						rmbStr = (new StringBuilder(String.valueOf(rmbStr))).append(chineseDigiStr[0]).toString();
					if (n != 1 || i % 4 != 1 || i != len - 1)
						rmbStr = (new StringBuilder(String.valueOf(rmbStr))).append(chineseDigiStr[n]).toString();
					rmbStr = (new StringBuilder(String.valueOf(rmbStr))).append(chineseDiviStr[i]).toString();
					hasvalue = true;
				} else
				if (i % 8 == 0 || i % 8 == 4 && hasvalue)
					rmbStr = (new StringBuilder(String.valueOf(rmbStr))).append(chineseDiviStr[i]).toString();
				if (i % 8 == 0)
					hasvalue = false;
				lastzero = n == 0 && i % 4 != 0;
			}

		if (rmbStr.length() == 0)
			return chineseDigiStr[0];
		else
			return rmbStr;
	}

	public static String numToRMBStr(double val)
	{
		String chineseDigiStr[] = {
			"零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"
		};
		String SignStr = "";
		String TailStr = "";
		if (val < 0.0D)
		{
			val = -val;
			SignStr = "负";
		}
		if (val > 100000000000000D || val < -100000000000000D)
			return I18n.ln(Amount, "2");
		long temp = Math.round(val * 100D);
		long integer = temp / 100L;
		long fraction = temp % 100L;
		int jiao = (int)fraction / 10;
		int fen = (int)fraction % 10;
		if (jiao == 0 && fen == 0)
		{
			TailStr = I18n.ln(Amount, "5");
		} else
		{
			TailStr = chineseDigiStr[jiao];
			if (jiao != 0)
				TailStr = (new StringBuilder(String.valueOf(TailStr))).append(I18n.ln(Amount, "6")).toString();
			if (integer == 0L && jiao == 0)
				TailStr = "";
			if (fen != 0)
				TailStr = (new StringBuilder(String.valueOf(TailStr))).append(chineseDigiStr[fen]).append(I18n.ln(Amount, "7")).toString();
		}
		return (new StringBuilder(String.valueOf(SignStr))).append(positiveIntegerToChinsesStr(String.valueOf(integer))).append(I18n.ln(Amount, "8")).append(TailStr).toString();
	}

	public static String numToRMBStr(double val, String currName)
	{
		String chineseDigiStr[] = {
			"零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"
		};
		String SignStr = "";
		String TailStr = "";
		if (val < 0.0D)
		{
			val = -val;
			SignStr = "负";
		}
		if (val > 100000000000000D || val < -100000000000000D)
			return "数值位数过大!";
		long temp = Math.round(val * 100D);
		long integer = temp / 100L;
		long fraction = temp % 100L;
		int jiao = (int)fraction / 10;
		int fen = (int)fraction % 10;
		if (jiao == 0 && fen == 0)
		{
			TailStr = "整";
		} else
		{
			TailStr = chineseDigiStr[jiao];
			if (jiao != 0)
				TailStr = (new StringBuilder(String.valueOf(TailStr))).append("角").toString();
			if (integer == 0L && jiao == 0)
				TailStr = "";
			if (fen != 0)
				TailStr = (new StringBuilder(String.valueOf(TailStr))).append(chineseDigiStr[fen]).append("分").toString();
		}
		return (new StringBuilder(String.valueOf(currName))).append(SignStr).append(positiveIntegerToChinsesStr(String.valueOf(integer))).append("元").append(TailStr).toString();
	}
	/**
	* 
	* @param numberOfMoney
	*            输入的金额
	* @return 对应的汉语大写
	*/		 
	public static String numToRMBStr(BigDecimal val) {
		StringBuffer sb = new StringBuffer();
		// -1, 0, or 1 as the value of this BigDecimal is negative, zero, or
		// positive.
		int signum = val.signum();
		// 零元整的情况
		if (signum == 0) {
			return CN_ZEOR_FULL;
		}
		//这里会进行金额的四舍五入
		long number = val.movePointRight(MONEY_PRECISION).setScale(0, 4).abs().longValue();
		// 得到小数点后两位值
		long scale = number % 100;
		int numUnit = 0;
		int numIndex = 0;
		boolean getZero = false;
		// 判断最后两位数，一共有四中情况：00 = 0, 01 = 1, 10, 11
		if (!(scale > 0)) {
			 numIndex = 2;
			 number = number / 100;
			 getZero = true;
		}
		if ((scale > 0) && (!(scale % 10 > 0))) {
			 numIndex = 1;
			 number = number / 10;
			 getZero = true;
		}
		int zeroSize = 0;
		while (true) {
		 	if (number <= 0) {
		 		break;
		}
		 // 每次获取到最后一个数
		numUnit = (int) (number % 10);
		if (numUnit > 0) {
			 if ((numIndex == 9) && (zeroSize >= 3)) {
				 sb.insert(0, CN_UPPER_MONETRAY_UNIT[6]);
			 }
			 if ((numIndex == 13) && (zeroSize >= 3)) {
				 sb.insert(0, CN_UPPER_MONETRAY_UNIT[10]);
			 }
			 sb.insert(0, CN_UPPER_MONETRAY_UNIT[numIndex]);
			 sb.insert(0, CN_UPPER_NUMBER[numUnit]);
			 getZero = false;
			 zeroSize = 0;
		} else {
			 ++zeroSize;
			 if (!(getZero)) {
				 sb.insert(0, CN_UPPER_NUMBER[numUnit]);
			 }
			 if (numIndex == 2) {
				 if (number > 0) {
					 sb.insert(0, CN_UPPER_MONETRAY_UNIT[numIndex]);
				 }
			 } else if (((numIndex - 2) % 4 == 0) && (number % 1000 > 0)) {
				 sb.insert(0, CN_UPPER_MONETRAY_UNIT[numIndex]);
			 }
			 getZero = true;
		}
		 // 让number每次都去掉最后一个数
			number = number / 10;
			++numIndex;
		}
		// 如果signum == -1，则说明输入的数字为负数，就在最前面追加特殊字符：负
		if (signum == -1) {
			sb.insert(0, CN_NEGATIVE);
		}
		// 输入的数字小数点后两位为"00"的情况，则要在最后追加特殊字符：整
		if (!(scale > 0)) {
			sb.append(CN_FULL);
		}
		return sb.toString();
	}	

	public static String number2En(double val)
	{
		String intString;
		String decString;
		String engCapital;
		String moneyString = getFormatedStr(val, 1);
		String tmpString[] = moneyString.split("\\.");
		intString = moneyString;
		decString = "";
		engCapital = "";
		StringBuffer strBuff1 = null;
		StringBuffer strBuff2 = null;
		StringBuffer strBuff3 = null;
		int curPoint = 0;
		int i1 = 0;
		int i2 = 0;
		int i3 = 0;
		int k = 0;
		int n = 0;
		if (tmpString.length > 1)
		{
			intString = tmpString[0];
			decString = tmpString[1];
		}
		try{
			decString = (new StringBuilder(String.valueOf(decString))).append("00").toString();
			decString = decString.substring(0, 2);
			curPoint = intString.length() - 1;
			if (curPoint >= 0 && curPoint < 15)
			{
				k = 0;
				for (; curPoint >= 0; curPoint -= 3)
				{
					strBuff1 = new StringBuffer("");
					strBuff2 = new StringBuffer("");
					strBuff3 = new StringBuffer("");
					if (curPoint >= 2)
					{
						n = Integer.parseInt(intString.substring(curPoint - 2, curPoint + 1));
						if (n != 0)
						{
							i1 = n / 100;
							i2 = (n - i1 * 100) / 10;
							i3 = n - i1 * 100 - i2 * 10;
							if (i1 != 0)
								strBuff1.append((new StringBuilder(String.valueOf(enSmallNumber[i1]))).append(" HUNDRED ").toString());
							if (i2 != 0)
							{
								if (i2 == 1)
								{
									strBuff2.append((new StringBuilder(String.valueOf(enSmallNumber[i2 * 10 + i3]))).append(" ").toString());
								} else
								{
									strBuff2.append((new StringBuilder(String.valueOf(enLargeNumber[i2 - 2]))).append(" ").toString());
									if (i3 != 0)
										strBuff3.append((new StringBuilder(String.valueOf(enSmallNumber[i3]))).append(" ").toString());
								}
							} else
							if (i3 != 0)
								strBuff3.append((new StringBuilder(String.valueOf(enSmallNumber[i3]))).append(" ").toString());
							engCapital = (new StringBuilder(String.valueOf(strBuff1.toString()))).append(strBuff2.toString()).append(strBuff3.toString()).append(enUnit[k]).append(" ").append(engCapital).toString();
						}
					} else
					{
						n = Integer.parseInt(intString.substring(0, curPoint + 1));
						if (n != 0)
						{
							i2 = n / 10;
							i3 = n - i2 * 10;
							if (i2 != 0)
							{
								if (i2 == 1)
								{
									strBuff2.append((new StringBuilder(String.valueOf(enSmallNumber[i2 * 10 + i3]))).append(" ").toString());
								} else
								{
									strBuff2.append((new StringBuilder(String.valueOf(enLargeNumber[i2 - 2]))).append(" ").toString());
									if (i3 != 0)
										strBuff3.append((new StringBuilder(String.valueOf(enSmallNumber[i3]))).append(" ").toString());
								}
							} else
							if (i3 != 0)
								strBuff3.append((new StringBuilder(String.valueOf(enSmallNumber[i3]))).append(" ").toString());
							engCapital = (new StringBuilder(String.valueOf(strBuff2.toString()))).append(strBuff3.toString()).append(enUnit[k]).append(" ").append(engCapital).toString();
						}
					}
					k++;
				}
	
				engCapital = engCapital.trim();
			}
			strBuff2 = new StringBuffer();
			strBuff3 = new StringBuffer();
			n = Integer.parseInt(decString);
			if (n != 0)
			{
				i2 = n / 10;
				i3 = n - i2 * 10;
				if (i2 != 0)
				{
					if (i2 == 1)
					{
						strBuff2.append((new StringBuilder(String.valueOf(enSmallNumber[i2 * 10 + i3]))).append(" ").toString());
					} else
					{
						strBuff2.append((new StringBuilder(String.valueOf(enLargeNumber[i2 - 2]))).append(" ").toString());
						if (i3 != 0)
							strBuff3.append((new StringBuilder(String.valueOf(enSmallNumber[i3]))).append(" ").toString());
					}
				} else
				if (i3 != 0)
					strBuff3.append((new StringBuilder(String.valueOf(enSmallNumber[i3]))).append(" ").toString());
				if (engCapital.length() > 0)
					engCapital = (new StringBuilder(String.valueOf(engCapital))).append(" AND CENTS ").append(strBuff2).append(strBuff3).toString();
				else
					engCapital = (new StringBuilder("CENTS ")).append(strBuff2).append(strBuff3).toString();
			}
			engCapital = engCapital.trim();
			return engCapital;
		}
		catch(Exception ex){
			ex.printStackTrace();
			return "";
		}
	}

	public static boolean isNumber(String str)
	{
		if (str == null || str.equals(""))
			return false;
		else
			return Pattern.matches("-?\\d*\\.?\\d+(E\\d+)?", str);
	}

	public static boolean isAmtNumber(String str)
	{
		if (str == null || str.equals(""))
			return false;
		else
			return Pattern.matches("-?\\d{1,3}(\\,\\d{3})*\\.\\d{0,8}", str);
	}

	public static boolean isInteger(String str)
	{
		if (str == null || str.equals(""))
			return false;
		else
			return Pattern.matches("(-?[1-9]\\d*)|0", str);
	}

	public static boolean isPositiveInteger(String str)
	{
		if (str == null || str.equals(""))
			return false;
		else
			return Pattern.matches("[1-9]\\d*", str);
	}

	public static boolean isAcctYMFormat(String str)
	{
		if (str == null || str.equals(""))
			return false;
		else
			return Pattern.matches("\\d{4}-\\d{2}", str);
	}

	public static boolean isSysDateFormat(String str)
	{
		if (str == null || str.equals(""))
			return false;
		if (str.length() < 10)
			return false;
		if (str.length() == 10)
			return Pattern.matches("\\d{4}-\\d{2}-\\d{2}", str);
		else
			return Pattern.matches("\\d{4}-\\d{2}-\\d{2}\\s{1}\\d{2}:\\d{2}:\\d{2}", str);
	}

	public static boolean isDay(String str)
	{
		if (str == null || str.equals(""))
			return false;
		if (str.length() < 10)
			return false;
		else
			return Pattern.matches("\\d{4}-\\d{2}-\\d{2}", str);
	}

	public static boolean isDayTime(String str)
	{
		if (str == null || str.equals(""))
			return false;
		if (str.length() < 19)
			return false;
		else
			return Pattern.matches("\\d{4}-\\d{2}-\\d{2}\\s{1}\\d{2}:\\d{2}:\\d{2}", str);
	}

	public static boolean isBracketMatched(String expr)
	{
		if (expr == null || expr.equals(""))
			return true;
		int tmpIndex = expr.indexOf('(');
		if (tmpIndex < 0)
			return true;
		int stackInt = 1;
		for (tmpIndex++; tmpIndex < expr.length();)
		{
			char c = expr.charAt(tmpIndex++);
			if (c == '(')
				stackInt++;
			else
			if (c == ')')
				stackInt--;
		}

		return stackInt == 0;
	}

	public static String num2Charactor(int num)
	{
		if (num < 10 || num > 35)
			return String.valueOf(num);
		else
			return String.valueOf((char)(55 + num));
	}

	/**
	 *  将数字字符串转化为Int型
	 * @param charactor 数字字符串
	 * @return　charactor为NULL或者为空时返回0 
	 */
	public static int str2Num(String charactor)
	{
		if (charactor == null || charactor.equals(""))
			return 0;
		int rtInt = 0;
		String tmpStr = charactor.toUpperCase();
		for (int i = 0; i < tmpStr.length(); i++)
		{
			char c = tmpStr.charAt(tmpStr.length() - 1 - i);
			rtInt += ((c - 65) + 1) * (int)Math.pow(26D, i);
		}

		return rtInt - 1;
	}
	/**
	 * 将字符串数据转化为Int型数值
	 * @param str字符串数值
	 * @return Int型数值
	 */
	public static int parseInt(String str)
	{
		return parseInt(str,0);
	}
	/**
	 * 将字符串数据转化为Int型数值
	 * @param str 字符串数值
	 * @param i  如为空或者NULL时的默认值
	 * @return  Int型数值
	 */
	public static int parseInt(String str, int i) {
		if(str==null || str.equals(""))return i;
		try{
			return Integer.parseInt(str);
		}
		catch(Exception ex){return i;}
	}

	/**
	 * 将字符串数据转化为BigDecimal型数值
	 * @param str字符串数值
	 * @return BigDecimal型数值
	 */
	public static BigDecimal parseBigDecimal(String str)
	{
		if(str==null || str.equals(""))return new BigDecimal(0);
		else return new BigDecimal(str);
	}
	
	/**
	 * 将字符串数据转化为BigDecimal型数值
	 * @param str 字符串数值
	 * @param i  如为空或者NULL时的默认值
	 * @return  BigDecimal型数值
	 */
	public static BigDecimal parseBigDecimal(String str, BigDecimal i) {
		if(str==null || str.equals(""))return i;
		try{
			return new BigDecimal(str);
		}
		catch(Exception ex){return i;}
	}
	/**
	 * 将long数据转化为BigDecimal型数值
	 * @param str字符串数值
	 * @return BigDecimal型数值
	 */
	public static BigDecimal parseBigDecimal(long str)
	{
		return new BigDecimal(str);
	}
	
	/**
	 * 将double数据转化为BigDecimal型数值
	 * @param str字符串数值
	 * @return BigDecimal型数值
	 */
	public static BigDecimal parseBigDecimal(double str)
	{
		return new BigDecimal(str);
	}

	/**
	 * 将float数据转化为BigDecimal型数值
	 * @param str字符串数值
	 * @return BigDecimal型数值
	 */
	public static BigDecimal parseBigDecimal(float str)
	{
		return new BigDecimal(str);
	}
	
	/**
	 * 将int数据转化为BigDecimal型数值
	 * @param str字符串数值
	 * @return BigDecimal型数值
	 */
	public static BigDecimal parseBigDecimal(int str)
	{
		return new BigDecimal(str);
	}

	/**
	 * 将日期字符串转化为日期Date型
	 * @param formatStr 转化格式 yyyy-MM-dd,yyyy年MM月dd日,MMMyyyy等
	 * @param dateStr 日期字符串
	 * @return 返回日期date型
	 * @throws ParseException
	 */
	public static Date parseDate(String formatStr, String dateStr)
		throws ParseException
	{
		if(dateStr==null || dateStr.length()<1)return new Date(0);
		SimpleDateFormat format = new SimpleDateFormat(formatStr);
		return format.parse(dateStr);
	}

	public static boolean isEqualAmt(double amt1, double amt2)
	{
		if (amt1 == amt2)
			return true;
		return Math.abs(amt1 - amt2) < Math.pow(10, 0 - decimalScale);
	}

	public static String decimal2DoubleStr(BigDecimal bgd)
	{
		return getFormatedStr(bgd.doubleValue(), 1);
	}

	public static BigDecimal add(double opt1, double opt2)
	{
		BigDecimal bgd1 = new BigDecimal(opt1);
		BigDecimal bgd2 = new BigDecimal(opt2);
		return add(bgd1, bgd2);
	}

	public static BigDecimal add(BigDecimal bgd1, double opt2)
	{
		BigDecimal bgd2 = new BigDecimal(opt2);
		return add(bgd1, bgd2);
	}

	public static BigDecimal add(BigDecimal opt1, BigDecimal opt2)
	{
		if (opt1 == null)
			opt1 = new BigDecimal(0.0D);
		if (opt2 == null)
			opt2 = new BigDecimal(0.0D);
		opt1 = opt1.setScale(decimalScale,BigDecimal.ROUND_HALF_UP);
		opt2 = opt2.setScale(decimalScale,BigDecimal.ROUND_HALF_UP);
		return opt1.add(opt2);
	}
	public static long LValue(BigDecimal opt1)
	{
		return LValue(opt1,decimalScale);
	}
	public static long IValue(BigDecimal opt1)
	{
		return LValue(opt1,decimalScale);
	}
	public static long getIntL(BigDecimal opt1)
	{
		return getIntL(opt1,decimalScale);
	}
	public static long getLongL(BigDecimal opt1)
	{
		return getLongL(opt1,decimalScale);
	}
	public static long LValue(BigDecimal opt1,int decimalScale)
	{
		if(decimalScale==1)return multiply(opt1,10).longValue();
		else if(decimalScale==2)return multiply(opt1,100).longValue();
		else if(decimalScale==3)return multiply(opt1,1000).longValue();
		else return multiply(opt1,10000).longValue();
	}
	public static long IValue(BigDecimal opt1,int decimalScale)
	{
		if(decimalScale==1)return multiply(opt1,10).intValue();
		else if(decimalScale==2)return multiply(opt1,100).intValue();
		else if(decimalScale==3)return multiply(opt1,1000).intValue();
		else return multiply(opt1,10000).intValue();
	}
	public static long getIntL(BigDecimal opt1,int decimalScale)
	{
		if(decimalScale==1)return multiply(opt1,10).intValue();
		else if(decimalScale==2)return multiply(opt1,100).intValue();
		else if(decimalScale==3)return multiply(opt1,1000).intValue();
		else return multiply(opt1,10000).intValue();
	}
	public static long getLongL(BigDecimal opt1,int decimalScale)
	{
		if(decimalScale==1)return multiply(opt1,10).longValue();
		else if(decimalScale==2)return multiply(opt1,100).longValue();
		else if(decimalScale==3)return multiply(opt1,1000).longValue();
		else return multiply(opt1,10000).longValue();
	}

	public static BigDecimal subtract(double opt1, double opt2)
	{
		BigDecimal bgd1 = new BigDecimal(opt1);
		BigDecimal bgd2 = new BigDecimal(opt2);
		return subtract(bgd1, bgd2);
	}

	public static BigDecimal subtract(BigDecimal bgd1, double opt2)
	{
		BigDecimal bgd2 = new BigDecimal(opt2);
		return subtract(bgd1, bgd2);
	}

	public static BigDecimal subtract(BigDecimal bgd1, long opt2)
	{
		BigDecimal bgd2 = new BigDecimal(opt2);
		return subtract(bgd1, bgd2);
	}

	public static BigDecimal subtract(BigDecimal bgd1, int opt2)
	{
		BigDecimal bgd2 = new BigDecimal(opt2);
		return subtract(bgd1, bgd2);
	}

	public static BigDecimal subtract(BigDecimal opt1, BigDecimal opt2)
	{
		if (opt1 == null)
			opt1 = new BigDecimal(0.0D);
		if (opt2 == null)
			opt2 = new BigDecimal(0.0D);
		opt1 = opt1.setScale(decimalScale,BigDecimal.ROUND_HALF_UP);
		opt2 = opt2.setScale(decimalScale,BigDecimal.ROUND_HALF_UP);
		return opt1.subtract(opt2);
	}

	public static BigDecimal multiply(BigDecimal opt1, long opt2)
	{
		BigDecimal bgd2 = new BigDecimal(opt2);
		return multiply(opt1, bgd2);
	}

	public static BigDecimal multiply(BigDecimal opt1, int opt2)
	{
		BigDecimal bgd2 = new BigDecimal(opt2);
		return multiply(opt1, bgd2);
	}

	public static BigDecimal multiply(BigDecimal bgd1, double opt2)
	{
		BigDecimal bgd2 = new BigDecimal(opt2);
		return multiply(bgd1, bgd2);
	}

	public static BigDecimal multiply(BigDecimal opt1, BigDecimal opt2)
	{
		if (opt1 == null)
			opt1 = new BigDecimal(0.0D);
		if (opt2 == null)
			opt2 = new BigDecimal(0.0D);
		opt1 = opt1.setScale(decimalScale,BigDecimal.ROUND_HALF_UP);
		opt2 = opt2.setScale(decimalScale,BigDecimal.ROUND_HALF_UP);
		return opt1.multiply(opt2);
	}

	public static BigDecimal divide(double opt1, double opt2)
	{
		BigDecimal bgd1 = new BigDecimal(opt1);
		BigDecimal bgd2 = new BigDecimal(opt2);
		return divide(bgd1, bgd2);
	}
	public static BigDecimal divide(BigDecimal bgd1, long opt2)
	{
		BigDecimal bgd2 = new BigDecimal(opt2);
		return divide(bgd1, bgd2);
	}
	
	public static BigDecimal divide(BigDecimal bgd1, int opt2)
	{
		BigDecimal bgd2 = new BigDecimal(opt2);
		return divide(bgd1, bgd2);
	}

	public static BigDecimal divide(BigDecimal bgd1, double opt2)
	{
		BigDecimal bgd2 = new BigDecimal(opt2);
		bgd2.setScale(2,BigDecimal.ROUND_HALF_UP);
		return divide(bgd1, bgd2);
	}

	public static BigDecimal divide(BigDecimal opt1, BigDecimal opt2)
	{
		if (opt1 == null)
			opt1 = new BigDecimal(0.0D);
		if (opt2 == null)
			opt2 = new BigDecimal(1.0D);
		opt1 = opt1.setScale(decimalScale,BigDecimal.ROUND_HALF_UP);
		opt2 = opt2.setScale(decimalScale,BigDecimal.ROUND_HALF_UP);
		return opt1.divide(opt2, decimalScale,BigDecimal.ROUND_HALF_UP);
	}

	public static String parseDoubleStr(BigDecimal bg, int format)
	{
		return getFormatedStr(bg.doubleValue(), format);
	}

	public static double parseDouble(BigDecimal bg)
	{
		if (bg == null)
			return 0.0D;
		else
			return Double.parseDouble(parseDoubleStr(bg, 1));
	}

	public static void str2Map(String propStr, Map<String,Object> rtMap)
	{
		String propArray[] = propStr.split("\\\r*\\\n{1}");
		for (int i = 0; i < propArray.length; i++)
		{
			String tmpStr = propArray[i].trim();
			if (tmpStr.length() >= 1 && !tmpStr.startsWith("#"))
			{
				int tmpIndex = tmpStr.indexOf("=");
				if (tmpIndex >= 0)
				{
					String key = tmpStr.substring(0, tmpIndex).trim();
					String value = tmpStr.substring(tmpIndex + 1).trim();
					if (key.length() >= 1 && value.length() >= 1)
						rtMap.put(key, value);
				}
			}
		}

	}

	public static void copyMap(Map<?, ?> fromMap, Map<Object, Object> toMap)
	{
		Object key;
		Object value;
		for (Iterator<?> iKeys = fromMap.keySet().iterator(); iKeys.hasNext(); toMap.put(key, value))
		{
			key = iKeys.next();
			value = fromMap.get(key);
		}

	}

	public static void clearMapPre(Map<?, ?> srcMap, String preFix)
	{
		List<String> keyList = new ArrayList<String>();
		for (Iterator<?> iKeys = srcMap.keySet().iterator(); iKeys.hasNext();)
		{
			String key = (String)iKeys.next();
			if (key.startsWith(preFix))
				keyList.add(key);
		}

		for (int i = 0; i < keyList.size(); i++)
			srcMap.remove(keyList.get(i));

	}

	public static void clearMapPost(Map<?, ?> srcMap, String postFix)
	{
		List<String> keyList = new ArrayList<String>();
		for (Iterator<?> iKeys = srcMap.keySet().iterator(); iKeys.hasNext();)
		{
			String key = (String)iKeys.next();
			if (key.endsWith(postFix))
				keyList.add(key);
		}

		for (int i = 0; i < keyList.size(); i++)
			srcMap.remove(keyList.get(i));

	}

	public static String encodeURL(String srcStr)
		throws Exception
	{
		if (srcStr == null)
			return "";
		else
			return URLEncoder.encode(srcStr, Const.DEFAULT_CODE);
	}

	public static String decodeURL(String srcStr)
		throws Exception
	{
		if (srcStr == null)
			return "";
		else
			return URLDecoder.decode(srcStr, Const.DEFAULT_CODE);
	}

	public static String encodeHtml(String srcStr)
	{
		if (srcStr == null)
			return "";
		else
			return srcStr.replace("\\", "&#92;").replace("\"", "&#34;").replace("'", "&#39;").replace("\r\n", "&#10;&#13;").replace("\n", "&#13;").replace("\r", "&#10;");
	}

	public static String encodeQuote(String srcStr)
	{
		if (srcStr == null)
			return "";
		else
			return srcStr.replace("\\", "\\\\").replace("\"", "\\\"").replace("'", "\\'");
	}

	public static String encodeSpecial(String srcStr)
	{
		if (srcStr == null)
			return "";
		else
			return srcStr.replace("\\", "\\\\").replace("\"", "\\\"").replace("'", "\\'").replace("\r\n", "").replace("\n", "").replace("\r", "");
	}

	public static String encodeLike(String srcStr)
	{
		if (srcStr == null)
			return "";
		else
			return srcStr.replace("\\", "\\\\").replace("'", "''").replace("%", "\\%").replace("_", "\\_");
	}
	public static double parseDouble(String numStr)
			throws ParseException
	{
		if (Utility.isNullorEmpty(numStr))
			return 0.0D;
		if (numStr.indexOf(",") > 0)
			return numFormatG.parse(numStr).doubleValue();
		else
			return Double.parseDouble(numStr);
	}
}
